package netTrackerGUI;

import netTracker.NetTracker;
import javax.swing.*;
import java.awt.event.*;
import java.util.*;

@SuppressWarnings("serial")	// Panel does not need to be serializable.

/**
 * 	The Tracker panel of the NetTracker GUI. Contains all the tracks and cells.
 * 	This class also handles keyboard events.
 */
public class TrackerPanel extends JPanel implements KeyListener{
	/** The NetTracker object for which this panel serves. */
	NetTracker netTracker;
	/** The NetTracker GUI which contains this panel. */
	NetTrackerGUI netTrackerGUI;
	/** The GUIs for each track. */ 
	TrackGUI[] tracks;
	JButton test;
	/** Keeps track of currently selected cell. */
	CellGUI selectedCell;
	/** Hash Map to keep track of currently outlined cells. 
	 * Key, Value is Owner ID, CellGUI instance */
	HashMap<Integer,CellGUI> outlinedCells;
	
	/**
	 * Constructs a panel for editing the song.
	 * @param netTracker the tracker that the editing panel is serving.
	 * @param netTrackerGUI the GUI for which contains this panel.
	 */
	public TrackerPanel(NetTracker netTracker, NetTrackerGUI netTrackerGUI){	
		this.netTracker = netTracker;
		this.netTrackerGUI = netTrackerGUI;
		
		outlinedCells = new HashMap<Integer, CellGUI>();
		
		/** Create and instantiate a GUI for each track: */
		tracks = new TrackGUI[netTracker.getNumTracks()];
		for (int i=0; i<tracks.length; i++){	
			tracks[i] = new TrackGUI(netTracker.getTracks()[i], netTrackerGUI, i);
			add(tracks[i]);													 // Add the track GUI.
			tracks[i].setLayout(new BoxLayout(tracks[i], BoxLayout.Y_AXIS)); // Set the track layout manager.
		}
		
		/** Create a margin around the tracker panel: */
		setBorder(BorderFactory.createEmptyBorder(NetTrackerGUI.MARGIN, NetTrackerGUI.MARGIN,
				NetTrackerGUI.MARGIN, NetTrackerGUI.MARGIN));
		
		setFocusable(true);			// Allow keyboard focus
		addKeyListener(this);		// Add a keyboard listener
	}

	/** 
	 * The following methods handle key events.
	 */
	public void keyPressed(KeyEvent e) {
		String key = KeyEvent.getKeyText(e.getKeyCode());
		if(selectedCell != null){	// Only perform move operations if a cell is selected.
			if(key.equals("Up"))
				moveCell(0,-1);
			else if (key.equals("Right"))
				moveCell(1,0);
			else if (key.equals("Down"))
				moveCell(0,1);
			else if (key.equals("Left"))
				moveCell(-1,0);
			else
				new Thread(new KeyPressedThread(key, this)).start();
		}
	}

	public void keyReleased(KeyEvent arg0) {
		// TODO Auto-generated method stub
	}

	public void keyTyped(KeyEvent arg0) {
		// TODO Auto-generated method stub
	}
	
	/**
	 * The following are getter and setter methods.
	 */
	
	/**
	 * Returns the currently selected cell.
	 * @return the currently selected cell.
	 */
	public CellGUI getSelectedCell(){
		return selectedCell;
	}
	/**
	 * Selects a given cell.
	 * @param selectedCell the cell to set as selected.
	 */
	public void setSelectedCell(CellGUI selectedCell){
		this.selectedCell=selectedCell;
	}
	/**
	 * Returns the currently outlined cell.
	 * @param outlineID the ID of the node outlining the cell.
	 * @return the currently outlined cell.
	 */
	public CellGUI getOutlinedCell(int outlineID){
		return outlinedCells.get(outlineID);
	}
	/**
	 * Selects a given cell.
	 * @param selectedCell the cell to set as selected.
	 */
	public void setOutlinedCell(CellGUI outlinedCell, int outlineID){
		outlinedCells.put(outlineID, outlinedCell);
	}
	
	/**
	 * Returns the Cell GUI at a given coordinate. 
	 * Note that (0,0) represents the top left cell.
	 * Wraps around using modulus operator.
	 * @param x the track to get the cell from.
	 * @param y the cell to get.
	 * @return
	 */
	public CellGUI getCell(int cellX, int cellY){
		if (cellX == -1)	// Account for wrap-around
			return tracks[tracks.length-1].getCell(cellY);
		return tracks[(cellX%tracks.length)].getCell(cellY);
	}
	
	/**
	 * @return if locking is turned on or off.
	 */
	public boolean isLocking(){
		return netTracker.isLocking();
	}
	
	/**
	 * Moves the currently selected cell by the given values.
	 * @param x the amount to move on the x-axis (positive goes right)
	 * @param y the amount to move on the y-axis (positive goes down)
	 */
	public void moveCell(int x, int y){
		new Thread(new CellSelectorThread(this, selectedCell, x, y)).start();
	}

	public HashMap<Integer, CellGUI> getOutlinedCells() {
		return outlinedCells;
	}
}